<template>
    <div>
        <div style="margin: 5px;text-align: center;">
            <el-input v-model="name" @click.enter.native="loadPost()" placeholder="请输入文件名称"
                style="width: 200px;margin-left: 5px;;" prefix-icon="el-icon-search"></el-input>
            <el-select v-model="status" @change="loadPost()" placeholder="请选择文件状态"
                style="width: 200px;margin-left: 5px;;">
                <el-option v-for="item in statusData" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>

            <el-button type="success" icon="el-icon-search" @click="loadPost()" circle
                style="margin-left: 5px;"></el-button>
            <el-button type="success" icon="el-icon-refresh" @click="resetParam" circle
                style="margin-left: 5px;"></el-button>
            <el-button type="primary" icon="el-icon-plus" @click="add" circle style="margin-left: 5px;"
                v-if="hasAuth('system:file-save')"></el-button>
            <el-button type="danger" icon="el-icon-delete" @click="delHandle(null)" circle style="margin-left: 5px;"
                v-if="hasAuth('system:file-delete')" :disabled="delBtnStatus"></el-button>

        </div>
        <el-table :data="tableData" ref="multipleTable" tooltip-effect="dark" border style="width: 100%" stripe
            @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="55"></el-table-column>

            <el-table-column label="文件名称" width="100" prop="name" align="center">
            </el-table-column>
            <el-table-column label="文件展示" width="100" prop="url" align="center">
                <template slot-scope="scope">
                    <div v-if="formatFileType(scope.row.type) === '图片'">
                        <el-image :src="scope.row.url" :preview-src-list="[scope.row.url]"
                            style="width: 100px; height: 100px;" fit="cover"></el-image>
                    </div>
                    <div v-else-if="formatFileType(scope.row.type) === '视频'">
                        <video src="scope.row.url" width="100" height="100" controls="controls"></video>
                    </div>
                    <div v-else-if="formatFileType(scope.row.type) === '音频'">
                        <audio src="scope.row.url" width="100" height="100" controls="controls"></audio>
                    </div>
                    <div>
                        <el-link type="primary" :href="scope.row.url" target="_blank">点击下载</el-link>
                    </div>
                </template>
            </el-table-column>
            <el-table-column label="文件大小" prop="size" align="center">
                <template slot-scope="scope">{{ formatFileSize(scope.row.size) }}</template>
            </el-table-column>
            <el-table-column label="文件类型" width="200" prop="type" align="center">
                <template slot-scope="scope">{{ formatFileType(scope.row.type) }}||{{ scope.row.type }}</template>

            </el-table-column>
            <el-table-column label="是否可用" width="200" prop="status" align="center">
                <template slot-scope="scope">
                    <el-switch :value="scope.row.status == 1" active-text="正常" active-color="#13ce66"
                        inactive-color="#ff4949" inactive-text="禁用" @change="modStatus(scope.row.id)"></el-switch>
                </template>
            </el-table-column>

            <el-table-column label="上传时间" width="180" prop="createTime" align="center"
                :formatter="formatDate"></el-table-column>


            <el-table-column label="操作" width="300" align="center" fixed="right">
                <template v-slot="scope">

                    <el-button type="danger" icon="el-icon-delete" @click="delHandle(scope.row.id)" circle
                        style="margin-left: 5px;" v-if="hasAuth('system:file-delete')"></el-button>




                </template>
            </el-table-column>
        </el-table>
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
            :page-size="pageSize" :page-sizes="[5, 20, 50, 100, 1000]" background
            layout="total,sizes,prev, pager, next,jumper" :total="total">
        </el-pagination>
        <el-dialog title="文件上传" :visible.sync="dialogVisible" width="80%" center>
            <el-form ref="form" :model="form" :rules="rules" label-width="150px"
                style="width: 1200px;margin: 10px auto;;" enctype="multipart/form-data">
                <el-form-item label="文件" prop="files">
                    <div class="upload-container">
                        <div class="upload-area" @dragover.prevent @drop.prevent="handleFolderDrop"
                            @click="handleInputClick">
                            <i class="el-icon-upload"></i>
                            <div class="el-upload_text">将文件拖拽至此处，或者点击上传文件</div>
                            <div class="el-upload_tip">
                                支持多文件上传，可上传任意格式文件
                            </div>

                        </div>
                        <input type="file" ref="fileInput" style="display: none;" @change="handleFileSelect" multiple
                            :limit="limit" />
                        <div class="file-list" v-if="fileList.length > 0">
                            <div class="file-item" v-for="(file, index) in fileList" :key="index">
                                <span class="file-name">{{ file.name }}</span>
                                <span class="file-size">{{ file.size ? formatFileSize(file.size) : '0B' }}</span>
                                <el-button type="danger" icon="el-icon-delete" circle
                                    @click="removeFile(index)"></el-button>
                            </div>
                        </div>

                    </div>
                </el-form-item>

            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="submitUpload" :loading="uploadLoading">上传</el-button>
            </div>
        </el-dialog>

    </div>
</template>
<script>

import { mapGetters } from 'vuex'
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: 'File',
    data() {
        return {
            user: JSON.parse(localStorage.getItem('CurUser')),
            tableData: [],

            total: 0,
            pageSize: 5,
            pageNum: 1,
            delBtnStatus: true,
            multipleSelection: [],
            name: '',

            status: 1,
            statusData: [
                {
                    id: 1,
                    name: "正常",
                },
                {
                    id: 0,
                    name: "禁用",
                },
            ],

            dialogVisible: false,
            form: {
                files: '',
            },
            rules: {
                files: [
                    { required: true, message: '文件不能为空', trigger: 'blur' },
                ],

            },
            limit: 10,
            fileList: [],
            uploadLoading: false,

        }
    }, methods: {
        loadPost() {
            this.$axios.post('/file/listPage',
                {
                    pageSize: this.pageSize,
                    pageNum: this.pageNum,
                    param: {
                        name: this.name + '',
                        status: this.status + ''
                    }
                }).then(res => {
                   
                    if (res.code == 200) {
                        this.tableData = res.data
                        // console.log(res.data)
                        if (res.data.length == 0 && this.pageNum != 1) {
                            this.pageNum = 1;
                            this.loadPost()
                        }
                        this.total = res.total
                    }
                })
        },
        resetParam() {
            this.name = ''

        },
        handleSizeChange(val) {
            this.pageSize = val
            this.pageNum = 1
            this.loadPost()
        },
        handleCurrentChange(val) {
            this.pageNum = val
            this.loadPost()
        },
        formatDate(row, column) {
            let data = row[column.property]
            if (data == null)
                return null
            let date = new Date(data)
            return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()
        },
        add() {
            this.resetForm()
            this.dialogVisible = true

        },

        resetForm() {
            this.form = {
                files: '',
            }
            this.fileList = []
        },

        handleSelectionChange(val) {
            this.multipleSelection = val
            this.delBtnStatus = val.length == 0
        },
        delHandle(id) {
            var ids = []
            if (id) {
                //单删
                ids.push(id)
            } else {
                //批量删
                this.multipleSelection.forEach(item => {
                    ids.push(item.id)
                })
            }
            this.$confirm('此操作将永久删除数据, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$axios.post('/file/deleteBatch', ids, {
                    headers: {
                        'Content-Type': 'application/json'
                    }
                }).then(res => {
                   
                    if (res.code == 200) {
                        this.$message({
                            message: '删除成功',
                            type: 'success'
                        })
                        this.loadPost()
                    } else {
                        this.$message({
                            message: '删除失败',
                            type: 'error'
                        })
                    }
                })
            }).catch(() => {
                this.$message({
                    message: '已取消',
                    type: 'info'
                })
            })
        },
        modStatus(id) {
            this.$axios.post('/file/modStatus/' + id).then(res => {
               
                if (res.code == 200) {
                    this.$message.success({
                        message: '操作成功',
                        type: 'success',
                        onClose: () => {
                            this.loadPost()
                        }
                    }
                    )
                } else {
                    this.$message({
                        message: '操作失败',
                        type: 'error'
                    })


                }
            })
        },
        formatFileSize(size) {
            if (size < 1024) {
                return size + 'B'
            } else if (size < 1048576) {
                return (size / 1024).toFixed(2) + 'KB'
            } else if (size < 1073741824) {
                return (size / 1048576).toFixed(2) + 'MB'
            } else if (size < 1099511627776) {
                return (size / 1073741824).toFixed(2) + 'GB'
            }
            else if (size < 1125899906842624) {
                return (size / 1099511627776).toFixed(2) + 'TB'
            } else {
                return (size / 1125899906842624).toFixed(2) + 'PB'
            }
        },
        formatFileType(type) {
            switch (type) {
                case 'doc':
                case 'docx':
                    return 'word文档'
                case 'xls':
                case 'xlsx':
                    return 'excel表格'
                case 'ppt':
                case 'pptx':
                    return 'ppt演示文稿'
                case 'pdf':
                    return 'pdf文件'
                case 'txt':
                    return 'txt文本'
                case 'zip':
                case 'rar':
                    return '压缩文件'
                case 'jpg':
                case 'jpeg':
                case 'png':
                case 'gif':
                    return '图片'
                case 'mp4':
                case 'avi':
                case 'wmv':
                case "mkv":
                    return '视频'
                case 'mp3':
                case 'wma':
                case 'wav':
                case 'flac':
                case 'aac':
                    return '音频'
                default:
                    return '未知文件'

            }
        },
        handleInputClick() {
            this.$refs.fileInput.click()
        },
        handleFolderDrop(e) {
            e.preventDefault()
            const items = e.dataTransfer.items
            this.processEntries(items)
        },
        handleFileSelect(e) {
            const files = e.target.files
            if (files.length > 0) {
                this.processFiles(files)
            }
        },
        processFiles(files) {
            const fileList = []
            // if (files.length > this.limit) {
            //     files = files.slice(0, this.limit)
            // }
            for (let i = 0; i < files.length; i++) {
                const file = files[i]
                file.relativePath = file.name
                fileList.push(file)
            }
            this.fileList.push(...fileList)
        },
        async processEntries(items) {
            let files = []
            const promises = []
            const processItem = (item, path = '') => {
                if (item.isFile) {
                    return new Promise(resolve => {
                        item.file(file => {
                            file.relativePath = path + file.name
                            files.push(file)
                            resolve()
                        })
                    })
                } else if (item.isDirectory) {
                    return new Promise(resolve => {
                        const dirReader = item.createReader()
                        dirReader.readEntries(entries => {
                            entries.forEach(entry => {
                                processItem(entry, path + item.name + '/')
                            })
                            resolve()
                        })
                    })

                }
            }
            for (let i = 0; i < items.length; i++) {

                const entry = items[i].webkitGetAsEntry()
                if (entry)
                    promises.push(processItem(entry))
            }
            await Promise.all(promises)
            // if (files.length > this.limit)
            //     files = files.slice(0, this.limit)
            this.fileList.push(...files)
        },
        async submitUpload() {
            if (this.fileList.length === 0) {
                this.$message.error('至少上传一个文件')
                return
            } if (this.fileList.length > this.limit) {
                this.$message.error('最多上传' + this.limit + '个文件')
                return
            }
            this.uploadLoading = true
            try {
                for (let i = 0; i < this.fileList.length; i++) {
                    const file = this.fileList[i]
                    if (file) {
                        await this.uploadFile(file)
                    }
                }
                this.$message.success('上传成功')
                this.dialogVisible = false
                this.loadPost()
                this.resetForm()

            } catch {
                this.$message.error('上传失败')
            } finally {
                this.uploadLoading = false
            }
        },
        async uploadFile(file) {
            return new Promise((resolve, reject) => {
                let formData = new FormData();
                formData.append("file", file);
                formData.append("name", file.name);
                this.$axios.post('/file/upload', formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                }).then(res => {
                   
                    console.log(res)
                    if (res.code == 200) {
                       resolve(res.data.url)
                    } else {
                        this.$message({
                            message: '上传失败',
                            type: 'error'
                        })
                    }
                }).catch(function (error) {
                    reject(error)
                })
            })
        },
    },
    computed: {
        ...mapGetters([
            'hasAuth'
        ])
    }, mounted() {
        this.loadPost()
    },
}
</script>
<style scoped>
.el-pagination {
    text-align: center;
    margin-top: 22px;
}

.upload-container {
    width: 100%;
}

.upload-area {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: border-color 0.3s;
    background-color: #fafafa;
    padding: 40px 0;
    text-align: center;
}

.upload-area:hover {
    border-color: #409eff;
}

.upload-area i {
    font-size: 67px;
    color: #c0c4cc;
    margin: 0 auto 10px;
    line-height: 50px;
}

.upload-area .el-upload__text {
    color: #606266;
    font-size: 14px;
    text-align: center;
}

.upload-area .el-upload__text em {
    color: #409eff;
    font-style: normal;
}

.upload-area .el-upload__tip {
    color: #909399;
    font-size: 12px;
    margin-top: 7px;
    text-align: center;
}

.file-list {
    margin-top: 20px;
    max-height: 300px;
    overflow-y: auto;
    border: 1px solid #ebeef5;
    border-radius: 4px;
    padding: 10px;
}

.file-item {
    display: flex;
    justify-content: space-between;
    padding: 8px 0;
    border-bottom: 1px solid #ebeef5;
}

.file-item:last-child {
    border-bottom: none;
}

.file-name {
    flex: 1;
    text-align: left;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-right: 10px;
}

.file-size {
    width: 100px;
    text-align: right;
    color: #909399;
    margin-right: 100px;
}
</style>